import java.util.HashMap;
import java.util.Map;

public class Test {
    public static void main(String[] args) {
        int[] nums = {1,2,1};
        Solution solution = new Solution();
        int ret = solution.totalFruit(nums);
        System.out.println(ret);
        int ret2 = solution.totalFruit2(nums);
        System.out.println(ret2);
    }
}

class Solution {
    public int totalFruit2(int[] fruits){
        int left = 0;
        int right = 0;
        int sum = 0;
        HashMap<Integer, Integer> map = new HashMap<>();
        for(right=0; right<fruits.length; right++){
            if(!map.containsKey(fruits[right])){//不存在这种水果
                if(map.size() >= 2){//其实应该没有大于2的可能
                    //那就维护一下窗口（这里的维护方法好像不太对）
                    while(map.size() >= 2){
                        map.remove(fruits[left++]);
                    }
                    //此时，窗口合法
                    map.put(fruits[right], right);
                    //每次放入，都应该更新一下结果，防止哪里没有执行到。
                    sum = Math.max(sum,right-left+1);
                }else{
                    map.put(fruits[right], right);
                    //每次放入，都应该更新一下结果，防止哪里没有执行到。
                    sum = Math.max(sum,right-left+1);
                }
            }else{//存在这种水果，直接“放”
                //continue;
                //放完更新一下结果（水果个数）
                sum = Math.max(sum,right - left + 1);
            }
        }
        return sum;
    }
    public int totalFruit(int[] fruits) {
        int left = 0;
        int i = 0;
        int len = fruits.length;
        int[] hash = new int[len];
        int count = 0;

        int sum = 0;
        for ( i = 0; i < len; i++) {
            if(hash[fruits[i]] == 0){
                count++;
                hash[fruits[i]] = 1;
                if(count > 2){
                    //更新结果
                    sum = Math.max(sum,i-left);

                    //出窗口，直到窗口内容符合要求
                    while(count>2){
                        hash[fruits[left]]--;
                        if(hash[fruits[left]] == 0){
                            count--;
                        }
                        left++;
                    }

                }else{
                    //这句感觉没必要，而且还跟复杂了，还有点问题continue;//窗口内容已经调整好了，继续吧。
                }
            }else{
                hash[fruits[i]]++;
            }
            sum = Math.max(sum,i-left+1);//前边的逻辑是：超过两种再计算，忽略了只有两种的情况。都没有执行到sum跟新那一句。
        }

        return sum;
    }
    public int totalFruit3(int[] fruits) {
        int left = 0;
        int right = 0;
        Map<Integer,Integer> map = new HashMap<Integer,Integer>();
        int sum = 0;
        for(right = 0; right < fruits.length; right++){
            //进窗口
            map.put(fruits[right],map.getOrDefault(fruits[right],0)+1);

            while(map.size() > 2){//判断
                //维护窗口（水果种类）
                map.put(fruits[left], map.get(fruits[left])-1);
                if(map.get(fruits[left])==0){
                    map.remove(fruits[left]);
                }
                left++;//出窗口
            }

            sum = Math.max(sum,right-left+1);
        }

        return sum;
    }
    public int totalFruit4(int[] fruits) {//老师讲的：模拟hash
        //
        int left = 0;
        int right = 0;
        int sum = 0;
        int count = 0;//窗口中的水果种类数
        int[] hash = new int[fruits.length];//下标——种类； 值——数量；
        for(right = 0; right < fruits.length; right++){
            //进窗口
            if(hash[fruits[right]] == 0){
                count++;
            }
            hash[fruits[right]]++;

            //维护窗口
            if(count > 2){
                hash[fruits[left]]--;
                if(hash[fruits[left]] == 0){
                    count--;
                }
                left++;
            }

            sum = Math.max(sum,right-left+1);
        }
        return sum;
    }
}
